<template>
  <div>
    <el-button-group>
      <el-button type="primary" :icon="CirclePlus" v-auth="'CreateJob'" @click="formVisible = true">
        新建定时任务
      </el-button>
      <el-button type="danger" :icon="Remove" v-auth="'DeleteJob'" @click="handleDeleteList">删除定时任务</el-button>
      <el-button type="success" :icon="Operation" v-auth="'OpenLog'" @click="handleOpenLog(undefined)">
        查看执行日志
      </el-button>
    </el-button-group>
    <x-table
      ref="refTable"
      name="定时任务"
      :columns="columns"
      :init-sort="{ jobName: 'ascending' }"
      :data="tableData.resp.list"
      :total="tableData.resp.total"
      :loading="tableData.loading"
      @query="handleQuery"
    >
      <template #column-misfirePolicy="scope">
        <el-tag :type="`${scope.data === '1' ? 'danger' : scope.data === '2' ? 'warning' : ''}`">
          {{ filtersText['misfirePolicy'][scope.data] }}
        </el-tag>
      </template>
      <template #column-concurrent="scope">
        <el-tag :type="`${scope.data === 0 ? 'warning' : 'success'}`">
          {{ filtersText['concurrent'][scope.data] }}
        </el-tag>
      </template>
      <template #column-status="scope">
        <el-tag v-if="!hasFuncKey('Run/Pause')" :type="`${scope.data === 0 ? 'info' : ''}`">
          {{ filtersText['status'][scope.data] }}
        </el-tag>
        <el-switch
          v-else
          :model-value="statusData[scope.row.jobId]"
          inline-prompt
          :active-value="1"
          :inactive-value="0"
          active-text="运行"
          inactive-text="暂停"
          inactive-color="#909399"
          @change="handleChange($event, scope.row)"
        />
      </template>
      <template #column-opera="scope">
        <div class="opera-col">
          <el-link
            v-if="hasFuncKey('EditJob')"
            plain
            type="primary"
            :underline="false"
            :icon="Edit"
            @click="handleOpenEditForm(scope.row)"
          >
            <span class="text">修改</span>
          </el-link>
          <el-popconfirm
            v-if="hasFuncKey('DeleteJob')"
            :title="`确定删除[ ${scope.row.jobName} ]吗?`"
            @confirm="handleDelete([scope.row.jobId], scope.row.jobName)"
          >
            <template #reference>
              <el-link plain type="danger" :underline="false" :icon="Remove">
                <span class="text">删除</span>
              </el-link>
            </template>
          </el-popconfirm>
          <el-dropdown>
            <span class="el-dropdown-link">
              <el-icon class="el-icon">
                <arrow-down />
              </el-icon>
              <span class="text">更多</span>
            </span>
            <template #dropdown>
              <el-dropdown-menu>
                <el-dropdown-item :icon="CaretRight" v-if="auth.run" @click="handleRun(scope.row)">
                  立即执行
                </el-dropdown-item>
                <el-dropdown-item :icon="Document" @click="handleDetail(scope.row)"> 任务详情 </el-dropdown-item>
                <el-dropdown-item :icon="Operation" v-if="auth.log" @click="handleOpenLog(scope.row)">
                  查看日志
                </el-dropdown-item>
              </el-dropdown-menu>
            </template>
          </el-dropdown>
        </div>
      </template>
    </x-table>
    <Form ref="refForm" v-model:visible="formVisible" @success="handleFormSuccess" />
    <FormDetail ref="refFormDetail" v-model:visible="formDetailVisible"></FormDetail>
  </div>
</template>

<script setup lang="ts">
import { computed, ref } from 'vue'
import { ElMessage, ElPopconfirm, ElTag, ElSwitch, ElDropdown, ElDropdownItem, ElDropdownMenu } from 'element-plus'
import { CirclePlus, Remove, Edit, ArrowDown, CaretRight, Document, Operation } from '@element-plus/icons-vue'
import { useRouter } from 'vue-router'
import { confirm } from '@/utils'
import { useColumn } from '@/hooks/column'
import { useAuth } from '@/hooks/auth'
import { jobApi } from '@/api/modules/job/job'
import type { Job } from '@/api/modules/job/job'
import { useJob } from './hook'
import Form from './Form.vue'
import FormDetail from './FormDetail.vue'

// 获取权限钩子，用于判断column中的修改和删除按钮 是否显示
const { hasFuncKey, hasFuncKeysCount } = useAuth()

const auth = computed(() => {
  return {
    run: hasFuncKey('ImmediatelyRun'),
    log: hasFuncKey('OpenLog')
  }
})
const { refTable, tableData, handleQuery, filters, filtersText, handleFormatter, statusData } = useJob()
const { columnOpera } = useColumn()
const hasCount = hasFuncKeysCount(['EditJob', 'DeleteJob'])
const columns = [
  { prop: 'jobName', width: 150, label: '任务名称', isGbk: true },
  { prop: 'invokeTarget', width: 250, label: '调用目标' },
  { prop: 'cronExpression', width: 150, label: 'cron表达式' },
  { prop: 'misfirePolicy', width: 120, label: '错误策略', formatter: handleFormatter, filters: filters.misfirePolicy },
  { prop: 'concurrent', width: 120, label: '是否并发', formatter: handleFormatter, filters: filters.concurrent },
  { prop: 'status', width: 100, label: '状态', formatter: handleFormatter, filters: filters.status },
  { prop: 'remark', width: 200, label: '备注' },
  { ...columnOpera, width: 75 * (hasCount + 1), isCreate: true }
]

const refForm = ref()
const formVisible = ref(false)

// 打开修改的窗口
const handleOpenEditForm = (data: Job) => {
  formVisible.value = true
  refForm.value.setFormData(data)
}

// 新建或修改成功后的回调函数，此刷新方法必须写在table组件所在的类文件中，否则执行其方法会出错
const handleFormSuccess = () => {
  refTable.value.refresh()
}

// 删除多个
const handleDeleteList = () => {
  if (refTable.value.selection.length === 0) {
    ElMessage.warning({ message: '请至少勾选列表中的一条数据' })
    return
  }
  confirm('确定要删除定时任务吗?', () => {
    handleDelete(
      refTable.value.selection.map((item: Job) => {
        return item.jobId
      })
    )
  })
}
// 执行删除操作
const handleDelete = (ids: string[], name = '') => {
  // log.action('删除定时任务')
  jobApi.delete(ids).then(resp => {
    if (resp.success) {
      refTable.value.refresh()
      ElMessage.success(name ? `定时任务[ ${name} ]已删除` : `${ids.length} 个定时任务已删除`)
    } else {
      ElMessage.error(resp.message)
    }
  })
}

const handleChange = (val: any, j: Job) => {
  const originVal = statusData[j.jobId]
  if (originVal === undefined || !j.jobId) return
  statusData[j.jobId] = val
  // log.action('运行/暂停定时任务')
  jobApi.updateStatus({ jobId: j.jobId, status: val } as Job).then(resp => {
    if (resp.success) {
      j.status = val
      ElMessage.success(`定时任务[ ${j.jobName} ]状态已更新`)
    } else {
      statusData[j.jobId] = originVal
      ElMessage.error(resp.message)
    }
  })
}

const handleRun = (job: Job) => {
  jobApi.run(job).then(resp => {
    if (resp.success) {
      ElMessage.success(`定时任务已执行`)
    } else {
      ElMessage.error(resp.message)
    }
  })
}

const refFormDetail = ref()
const formDetailVisible = ref(false)
const handleDetail = (data: Job) => {
  formDetailVisible.value = true
  refFormDetail.value.setFormData(data)
}

const router = useRouter()
const handleOpenLog = (data?: Job) => {
  router.push({ path: '/system/job/log', query: { jobName: data?.jobName } })
}
</script>

<style lang="scss" scoped>
.opera-col {
  display: flex;
  align-items: center;
  justify-content: space-around;
  .text {
    padding: 0 2px;
  }
  .el-dropdown-link {
    cursor: pointer;
    display: flex;
    align-items: center;
    color: var(--el-color-primary);
  }
}
:deep(.el-switch__core) {
  width: 50px;
}
</style>
